package com.haojiang.mh.widget.chart;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.*;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import com.haojiang.mh.R;
import com.haojiang.mh.service.entity.EvaluateBean;
import com.haojiang.mh.utils.ImageUtil;
import com.haojiang.mh.utils.SizeUtil;
import com.haojiang.mh.widget.OnScoreBallClickListener;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 睡眠评分图标（如果当天没有数据则不显示）
 * 当前用在《周报》
 */
public class EvaluateChatView extends View {

    private TextPaint textPaint;//文本画笔
    //坐标刻度、柱子、圆球背景 画笔
    private Paint coordinatePaint, columnPaint, layerPaint;
    //Y轴宽度、X轴文字高度、X轴高度、绘制高度、柱子宽度、Y轴文本高度、Y轴起点
    private int yAxisWidth, xAxisTextHeight, xAxisHeight, drawHeight, columnWidth, yAxisTextHeight, bottomY;
    private float xItemWidth, yItemHeight;//X轴间隔块宽度、Y轴间隔块高度
    //Y轴起点、Y轴间隔值、Y轴坐标个数（除起点）、Y轴最大刻度
    private int yStartCoordinate, yInterval, yCoordinateNum, yMaxCoordinate;
    private int layerBallRadius;//图层球半径大小
    private int width, height, defaultWidth, defaultHeight;//当前View宽高、默认宽高
    private Bitmap bestStar;//最佳
    private int workDayColor, weekendColor, ballInnerTextColor;//工作日、周末、球内文字 颜色值
    private int highScoreColor, midScoreColor, lowScoreColor;//最高、中等、最低 背景层颜色
    private int columnGraTopColor, columnGraBottomColor;//现行渐变顶部、底部颜色值
    private int xAxisTextSize, yAxisTextSize;//X,Y轴文本字体大小
    private String[] weekText;//一周文本
    private List<EvaluateBean> beanList;//数据集
    private LinearGradient shader;//线性渐变
    //用于点击事件
    private Map<Rect, EvaluateBean> rectEntryMap = new HashMap<>();
    //按下时间
    private long pressTime = 0;
    //是否按在value line上
    private boolean isDownLineValue = false;
    //触摸矩阵
    private Rect downRect = null;
    //按钮callback
    private OnScoreBallClickListener mOnScoreBallClickListener;

    public EvaluateChatView(Context context) {
        this(context, null);
    }

    public EvaluateChatView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public EvaluateChatView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        @SuppressLint("CustomViewStyleable")
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ChartModuleAttribute, defStyleAttr, 0);
        yStartCoordinate = a.getInt(R.styleable.ChartModuleAttribute_cm_y_start, 0);
        yInterval = a.getInt(R.styleable.ChartModuleAttribute_cm_y_interval, 20);
        yCoordinateNum = a.getInt(R.styleable.ChartModuleAttribute_cm_y_number, 5);
        a.recycle();

        initView(context);
    }

    public void setOnScoreBallClickListener(OnScoreBallClickListener onScoreBallClickListener) {
        mOnScoreBallClickListener = onScoreBallClickListener;
    }

    private void initView(Context context) {
        yAxisWidth = SizeUtil.dp2px(context, 40);
        xAxisTextHeight = SizeUtil.dp2px(context, 40);
        yAxisTextHeight = SizeUtil.dp2px(context, 20);
        columnWidth = SizeUtil.dp2px(context, 2);
        xAxisHeight = SizeUtil.dp2px(context, 3);
        drawHeight = SizeUtil.dp2px(context, 150);
        layerBallRadius = SizeUtil.dp2px(context, 15);

        defaultWidth = SizeUtil.dp2px(context, 340);
        defaultHeight = xAxisTextHeight + drawHeight + xAxisHeight + xAxisTextHeight;

        weekText = getResources().getStringArray(R.array.chinaWeekDayArray);
        workDayColor = getResources().getColor(R.color.white_half);
        weekendColor = getResources().getColor(R.color.purple_3);
        columnGraTopColor = getResources().getColor(R.color.grey_5);
        columnGraBottomColor = columnGraTopColor & 0x00FFFFFF;
        ballInnerTextColor = getResources().getColor(R.color.white);
        highScoreColor = getResources().getColor(R.color.purple_3);
        midScoreColor = getResources().getColor(R.color.purple_5);
        lowScoreColor = getResources().getColor(R.color.grey_3);

        bestStar = ImageUtil.getBitmapFromDrawable(context, R.drawable.ic_best_star);

        xAxisTextSize = SizeUtil.sp2px(context, 14);
        yAxisTextSize = SizeUtil.sp2px(context, 12);

        coordinatePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        coordinatePaint.setStyle(Paint.Style.FILL);
        coordinatePaint.setColor(workDayColor);

        columnPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        columnPaint.setStyle(Paint.Style.FILL);

        layerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        layerPaint.setStyle(Paint.Style.FILL);

        textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setTextAlign(Paint.Align.CENTER);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mOnScoreBallClickListener == null || rectEntryMap.isEmpty()) {
            return super.onTouchEvent(event);
        }
        int downX, downY, upX, upY;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                pressTime = System.currentTimeMillis();
                downX = (int) event.getX();
                downY = (int) event.getY();
                for (Rect next : rectEntryMap.keySet()) {
                    if (downX > next.left && downX < next.right && downY < next.bottom && downY > next.top) {
                        isDownLineValue = true;
                        downRect = next;
                        //接受后续事件
                        return true;
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                upX = (int) event.getX();
                upY = (int) event.getY();
                //触摸事件小于200 算点击时间
                if (isDownLineValue && System.currentTimeMillis() - pressTime < 200) {
                    if (upX > downRect.left && upX < downRect.right && upY < downRect.bottom && upY > downRect.top) {
                        EvaluateBean entry = rectEntryMap.get(downRect);
                        if (entry != null) {
                            mOnScoreBallClickListener.onClick(entry.getDate());
                        }
                    }
                }
                break;
        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (beanList == null || beanList.isEmpty()) return;

        yMaxCoordinate = yStartCoordinate + yInterval * yCoordinateNum;
        xItemWidth = (float) (width - yAxisWidth) / 7;
        yItemHeight = (float) drawHeight / yCoordinateNum;
        bottomY = height - xAxisTextHeight - xAxisHeight;

        drawXAxis(canvas);

        drawYAxis(canvas);

        drawColumn(canvas);
    }

    /**
     * 绘制X轴
     */
    private void drawXAxis(Canvas canvas) {
        textPaint.setTextSize(xAxisTextSize);
        for (int i = 0; i < beanList.size(); i++) {
            textPaint.setColor((i == 5 || i == 6) ? weekendColor : workDayColor);
            canvas.drawText(
                    weekText[i],
                    xItemWidth * i + xItemWidth * 0.5f,
                    SizeUtil.getBaseLine(textPaint, xAxisTextHeight, xAxisTextHeight),
                    textPaint
            );
            canvas.drawLine(//坐标刻度
                    xItemWidth * i + xItemWidth * 0.5f,
                    bottomY,
                    xItemWidth * i + xItemWidth * 0.5f,
                    bottomY + xAxisHeight,
                    coordinatePaint
            );
            canvas.drawText(
                    beanList.get(i).getDay(),
                    xItemWidth * i + xItemWidth * 0.5f,
                    SizeUtil.getBaseLine(textPaint, height, xAxisTextHeight),
                    textPaint
            );
        }
    }

    /**
     * 绘制Y轴
     */
    private void drawYAxis(Canvas canvas) {
        textPaint.setColor(workDayColor);
        textPaint.setTextSize(yAxisTextSize);
        for (int i = 0; i <= yCoordinateNum; i++) {
            canvas.drawCircle(
                    width - yAxisWidth,
                    bottomY - yItemHeight * i,
                    5,
                    coordinatePaint
            );
            if (i == 0) continue;
            canvas.drawText(
                    String.valueOf(yStartCoordinate + i * yInterval),
                    width - yAxisWidth * 0.5f,
                    SizeUtil.getBaseLine(textPaint, bottomY - yItemHeight * i + yAxisTextHeight * 0.5f, yAxisTextHeight),
                    textPaint
            );
        }
    }

    /**
     * 绘制渐变轴+圆球+得分
     */
    private void drawColumn(Canvas canvas) {
        rectEntryMap.clear();
        for (int i = 0; i < beanList.size(); i++) {
            float xItemMidPosition = xItemWidth * i + xItemWidth * 0.5f;
            EvaluateBean bean = beanList.get(i);
            if (bean == null || bean.isNull()) continue;
            float top = bottomY - getScoreHeight(bean.getScore()) + layerBallRadius * 2;
            shader = new LinearGradient(0, bottomY, 0, top, columnGraBottomColor, columnGraTopColor, Shader.TileMode.CLAMP);
            columnPaint.setShader(shader);
            canvas.drawRect(//渐变线条
                    xItemMidPosition - columnWidth * 0.5f,
                    top,
                    xItemMidPosition + columnWidth * 0.5f,
                    bottomY,
                    columnPaint
            );
            //layer层
            layerPaint.setColor(getLayerColor(bean.getScore()));
            //绘制球体
            canvas.drawCircle(xItemMidPosition, top - layerBallRadius, layerBallRadius, layerPaint);
            //球体矩阵
            Rect rect = new Rect(((int) (xItemMidPosition - layerBallRadius)), ((int) (top - 2 * layerBallRadius)), ((int) (xItemMidPosition + layerBallRadius)), (int) top);
            rectEntryMap.put(rect, bean);
            textPaint.setColor(ballInnerTextColor);
            canvas.drawText(//球内文字
                    String.valueOf(bean.getScore()),
                    xItemMidPosition,
                    SizeUtil.getBaseLine(textPaint, top, layerBallRadius * 2),
                    textPaint
            );
            if (getBestScore() != bean.getScore()) continue;
            //最佳得分
            canvas.drawBitmap(bestStar, xItemMidPosition - layerBallRadius, top - layerBallRadius * 2, null);
        }
    }

    /**
     * 获取得分高度所占比
     */
    private float getScoreHeight(int score) {
        return (score - yStartCoordinate) * drawHeight * 1.0f / (yMaxCoordinate - yStartCoordinate);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(
                getMeasuredLength(widthMeasureSpec, true),
                getMeasuredLength(heightMeasureSpec, false)
        );
    }

    private int getMeasuredLength(int length, boolean isWidth) {
        int specMode = MeasureSpec.getMode(length);
        int specSize = MeasureSpec.getSize(length);
        int size;
        int padding = isWidth ? getPaddingLeft() + getPaddingRight() : getPaddingTop() + getPaddingBottom();
        if (specMode == MeasureSpec.EXACTLY) {
            size = specSize;
        } else if (specMode == MeasureSpec.UNSPECIFIED) {
            size = isWidth ? defaultWidth : defaultHeight;
        } else {
            size = isWidth ? padding + defaultWidth : padding + defaultHeight;
            if (specMode == MeasureSpec.AT_MOST) {
                size = Math.min(size, specSize);
            }
        }
        return size;
    }

    /**
     * 获取圆球背景层背景色
     */
    public int getLayerColor(int score) {
        int layerColor;
        if (score > 85) {
            layerColor = highScoreColor;
        } else if (score >= 70) {
            layerColor = midScoreColor;
        } else {
            layerColor = lowScoreColor;
        }
        return layerColor;
    }

    /**
     * 获取最高得分
     */
    private int getBestScore() {
        if (beanList == null || beanList.isEmpty()) return -1;
        int bestScore = 0;
        for (EvaluateBean eb : beanList) {
            if (eb.getScore() > bestScore) {
                bestScore = eb.getScore();
            }
        }
        return bestScore;
    }

    public void setChartData(List<EvaluateBean> data) {
        if (beanList == null) beanList = new ArrayList<>();
        beanList.clear();
        if (data != null && !data.isEmpty()) {
            beanList.addAll(data);
        }
        invalidate();
    }
}

